Cú pháp C_(ngôn_ngữ_lập_trình)

C có nhiều điểm yếu trong cú pháp. Đáng chú ý là:

  • Nguyên mẫu của hàm nào không chỉ ra tham số nào thì được hiểu ngầm là cho phép một tập bất kì các tham số. Một vấn đề về cú pháp đã được đề ra cho khả năng tương thích ngược của K&R C, về việc thiếu các nguyên mẫu.
  • Một số sự chọn lựa đáng ngờ vực về thứ tự ưu tiên của các toán tử, chẳng hạn như == "nối kết" một cách chặt chẽ hơn &| trong các biểu thức như là x & 1 == 0.
  • Việc dùng toán tử "=" một cách dễ nhầm lẫn. Nếu dùng trong đẳng thức toán học để chỉ các phép gán, dẫn tới các phép gán không chủ định trong việc so sánh và dẫn tới một ấn tượng sai lầm rằng phép gán có tính bắc cầu. Ví dụ: việc dùng câu lệnh if (x=0) {...} sẽ dễ gây ra các lỗi bất ngờ.
  • Thiếu các toán tử infix cho các đối tượng phức tạp, đặc biệt là cho các phép toán trên dãy các ký tự làm cho chương trình phụ thuộc nặng nề lên các phép toán rất khó đọc.
  • Dựa vào quá nhiều trên hệ thống ký hiệu làm cơ sở cho cú pháp ngay cả ở nơi không tường minh như là "&&" và "||" thay vì dùng "and" và "or".
  • Cú pháp khai báo không được dễ hiểu, đặc biệt cho hàm của các con trỏ. Trong tình huống hoàn toàn tương tự của C++, nhà nghiên cứu Damian Conway nói về cú pháp của khai báo như sau:Khó để mà đặc tả một kiểu trong C++ bởi vì thực tế là một số phần tử của việc khai báo (như là con trỏ) thì là các toán tử tiền tố trong khi một số khác (như là mảng) lại là toán tử hậu tố (nghĩa là phải đặt * đứng trước tên con trỏ và dặt [] sau tên mảng—người dịch). Nhừng toán tử khai báo này lại có các thứ tự ưu tiên khác nhau, cần phải được đặt trong các dấu ngoặc cẩn thận để đạt được sự khai báo mong muốn.Ben Werther & Damian Conway.

A Modest Proposal: C++ Resyntaxed. Section 3.1.1. 1996.

Các vấn đề về bảo trì

Có một số vấn đề khác của C mà không trực tiếp do các lỗi hay sai sót, nhưng lại làm ngăn trở khả năng của người lập trình để xây đựng một hệ thống cỡ lớn, có thể bảo trì và ổn định. Các điển hình bao gồm:

  • Hệ thống rời rạc vì các câu lệnh định nghĩa nhập (#include) dựa trên các dòng chữ nội tại rải rác không đồng nhất (trong các tập tin) nhằm giữ các nguyên mẫu và các định nghĩa được đồng bộ. Điều này làm tăng đáng kể số lần cho việc tạo dựng (phần mềm).
  • Mô hình chuyển dịch rối rắm. Nó buộc phải có việc theo dõi các sự phụ thuộc (về mã) bằng tay và nó ngăn cấm sự tối ưu hóa trình dịch giữa các mô dun (ngoại trừ sự tối ưu hoá thời gian liên kết).
  • Hệ thống kiểu yếu dẫn tới việc các chương trình có lỗi hiển nhiên nhưng vẫn được dịch mà không bị bắt lỗi.

Các công cụ kiểm tra tĩnh cho trình dịch

Nhiều công cụ đã được tạo ra để giúp người lập trình C tránh dược các lỗi. Việc kiểm tra và kiểm toán mã nguồn tự động thì rất hiệu quả trong mọi ngôn ngữ. Chẳng hạn cho C là Lint. Một thực tế là sử dụng Lint để phát hiện các mã có nghi vấn khi một chương trình được viết lần đầu. Một khi chương trình đã qua được Lint, thì nó được chuyển dịch bởi một trình dịch C. Cũng có một thư viện cho việc tiến hành kiểm tra các biên của mảng và một dạng giới hạn của việc tự động dọn rác, nhưng đó không phải là một phần tiêu chuẩn của C.

Điều nên nhận thức là các công cụ này không phải là vạn năng. Bởi vì sự linh hoạt của C, nhiều kiểu lỗi như là việc dùng sai các hàm tham lượng động, việc dùng chỉ số ngoài biên của mảng và quản lý bộ nhớ không đúng thì không thể phát hiện được. Mặc dù vậy, nhiều trường hợp (lỗi) thông thường đều có thể được nhận ra.

Tài liệu tham khảo

WikiPedia: C_(ngôn_ngữ_lập_trình) http://www.csse.monash.edu.au/~damian/papers/HTML/... http://www.research.att.com/~bs/bs_faq.html#really... http://www.research.att.com/~bs/sibling_rivalry.pd... http://cm.bell-labs.com/cm/cs/who/dmr/chist.html http://cm.bell-labs.com/cm/cs/who/dmr/spacetravel.... http://www-106.ibm.com/developerworks/linux/librar... http://homepage.ntlworld.com/dmjones/cbook1_0a.pdf http://david.tribble.com/text/cdiffs.htm http://www.library.cornell.edu/nr/bookcpdf/c1-2.pd... http://catalogue.bnf.fr/ark:/12148/cb119665180